// Copyright(c) 2011 Matthew McMullan, Jorel Lalicki and Mike Heise, Jorel Lalicki and Mike Heise. See copying.txt for details.

/*! \file
	Defines a set of standard names for fixed width data types and is intended to
remove compiler, platform, and architecture dependence of software based on the differences
in the meanings of standard variable names.

The following naming conventions are used. Each name consists of at least two parts, a prefix
and a bit width.

Prefix table:
i	Signed Integer Type
		Valid Instances: i8, i16, i32, i64
u	Unsigned Integer Type
		Valid Instances: u8, u16, u32, u64
f	Floating Point Type
		Valid Instances: f32, f64

Each type has coresponding declarations:
TYPENAME_min	minimum value storable
TYPENAME_max	maximum value storable
TYPENAME_fast	a fast INTEGER ONLY type bit width is a MINIMUM, not exact bit width - is
		usually the native size of the CPU registers

These values will be set for the safe value guaranteed by the C standard and compatible with
one's complement and two's complement systems.
*/

#ifndef __agml_fixed_h__
#define __agml_fixed_h__

// make sure that this file is never included directly
#ifndef __agml_agml_h__
#error "Include AGML from agml.h only. This file is not a valid entry point for the library."
#endif

// Includes
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>		// the C99 integer types
#include <float.h>

namespace agml {

typedef uintptr_t		uptr;
typedef intptr_t		iptr;

// Define Integer Types
/*! An 8-bit signed int. */
typedef int8_t			i8;
/*! An 8-bit signed int. May be a larger size for faster aligned memory usage. */
typedef int_fast8_t		i8_fast;
/*! Minimum value for i8 and i8_fast types */
static const i8 i8_min	= -128;
/*! Maximum value for i8 and i8_fast types */
static const i8 i8_max = 127;

/*! An 8-bit unsigned int. */
typedef uint8_t			u8;
/*! An 8-bit unsigned int. May be a larger size for faster aligned memory usage. */
typedef uint_fast8_t	u8_fast;
/*! Minimum value for u8 and u8_fast types */
static const u8 u8_min = 0;
/*! Maximum value for u8 and u8_fast types */
static const u8 u8_max = 255;

/*! A 16-bit signed int. */
typedef int16_t			i16;
/*! A 16-bit signed int. May be a larger size for faster aligned memory usage. */
typedef int_fast16_t	i16_fast;
/*! Minimum value for i16 and i16_fast types */
static const i16 i16_min = -32768;
/*! Minimum value for i16 and i16_fast types */
static const i16 i16_max = 32767;

/*! A 16-bit unsigned int. */
typedef uint16_t		u16;
/*! A 16-bit unsigned int. May be a larger size for faster aligned memory usage. */
typedef uint_fast16_t	u16_fast;
/*! Minimum value for u16 and u16_fast types */
static const u16 u16_min = 0;
/*! Minimum value for u16 and u16_fast types */
static const u16 u16_max = 0xffff;

/*! A 32-bit signed int. */
typedef int32_t			i32;
/*! A 32-bit signed int. May be a larger size for faster aligned memory usage. */
typedef int_fast32_t	i32_fast;
/*! Minimum value for i32 and i32_fast types */
static const i32 i32_min = -2147483647 - 1;
/*! Maximum value for i32 and i32_fast types */
static const i32 i32_max = 2147483647;

/*! A 32-bit unsigned int. */
typedef uint32_t		u32;
/*! A 32-bit unsigned int. May be a larger size for faster aligned memory usage. */
typedef uint_fast32_t	u32_fast;
/*! Minimum value for u32 and u32_fast types */
static const u32 u32_min = 0;
/*! Maximum value for u32 and u32_fast types */
static const u32 u32_max = 0xffffffff;

/*! A 64-bit signed int. */
typedef int64_t			i64;
/*! A 64-bit signed int. May be a larger size for faster aligned memory usage. */
typedef int_fast64_t	i64_fast;
/*! Minimum value for i64 and i64_fast types */
static const i64 i64_min = 0x1000000000000000LL; //-9223372036854775808LL
/*! Minimum value for i64 and i64_fast types */
static const i64 i64_max = 9223372036854775807LL;

/*! A 64-bit unsigned int. */
typedef uint64_t		u64;
/*! A 64-bit unsigned int. May be a larger size for faster aligned memory usage. */
typedef uint_fast64_t	u64_fast;
/*! Minimum value for u64 and u64_fast types */
static const u64 u64_min = 0;
/*! Minimum value for u64 and u64_fast types */
static const u64 u64_max = 0xffffffffffffffffULL;

// Define Floating Point Types
/*! A 32-bit floating point number */
typedef float	f32;
/*! Minimum value for the f32 type */
static const f32 f32_min = FLT_MIN;
/*! Maximum value for the f32 type */
static const f32 f32_max = FLT_MAX;
/*! Delta-value for comparisons with the f32 type */
static const f32 f32_eps = FLT_EPSILON;
/*! Maximum number of decimal digits storable with the f32 type while retaining full precision */
static const u32_fast f32_dig = 6;

/*! A 64-bit floating point number */
typedef double	f64;
/*! Minimum value for the f64 type */
static const f64 f64_min = DBL_MIN;
/*! Maximum value for the f64 type */
static const f64 f64_max = DBL_MAX;
/*! Delta-value for comparisons with the f64 type */
static const f64 f64_eps = DBL_EPSILON;
/*! Maximum number of decimal digits storable with the f32 type while retaining full precision */
static const u32_fast f64_dig = 15;

/*! A 80-bit floating point number */
typedef long double	f80;
/*! Minimum value for the f80 type */
static const f80 f80_min = LDBL_MIN;
/*! Maximum value for the f80 type */
static const f80 f80_max = LDBL_MAX;
/*! Delta-value for comparisons with the f80 type */
static const f80 f80_eps = LDBL_EPSILON;
/*! Maximum number of decimal digits storable with the f80 type while retaining full precision */
static const u32_fast f80_dig = 18;

typedef const u8 Cu8;
typedef const u16 Cu16;
typedef const u32 Cu32;
typedef const u64 Cu64;
typedef const i8 Ci8;
typedef const i16 Ci16;
typedef const i32 Ci32;
typedef const i64 Ci64;
typedef const f32 Cf32;
typedef const f64 Cf64;
typedef const f80 Cf80;
typedef const uptr Cuptr;
typedef const iptr Ciptr;

}

#endif
